
#include "CTestScreen.h"
#include "CGamePauseScreen.h"
#include <QString>
#include <QMessageBox>
#include <fstream>
#include <iomanip>
#include "CSound.h"

void CTestScreen::load(CGraphics *gl)
{
    // slepia foninį screen, jei toks yra
    CScreen* background = sm->getScreen("backgroundScreen");
    if ( background != 0 ) background->setHidden( true );

    // tekstūrų užloadinimas
    gl->loadTexture( QString::fromStdWString(L"./img/tex0.jpg"), textures[0] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex1.png"), textures[1] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex2.png"), textures[2] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex3.png"), textures[3] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex4.png"), textures[4] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex5.png"), textures[5] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex6.png"), textures[6] );
    gl->loadTexture( QString::fromStdWString(L"./img/tex7.png"), textures[7] );
    gl->loadTexture( QString::fromStdWString(L"./img/mask.png"), textures[8] );
    gl->loadTexture( QString::fromStdWString(L"./img/cue.png"), textures[9] );
    gl->loadTexture( QString::fromStdWString(L"./img/kamuoliukai.png"), textures[10] );

    font = QFont( "Verdana", 10, 0, 0 );

    // kamuoliuku spalvos
    int c[] = { 255,255,255,  255,200,  0,   31, 61,197, 233,  0,  0,
                 95,  0,115,  255,100,  0,    0,100,  0, 100, 10,  0,
                  0,  0,  0,  255,200,  0,   31, 61,197, 233,  0,  0,
                 95,  0,115,  255,100,  0,    0,100,  0, 100, 10,  0,};
    for ( int i = 0; i < 16; i++ )
        for ( int j = 0; j < 3; j++ )
            col[i][j] = c[i*3+j];

    // sienų splainai
    double s[] = {
                     0.0,   0.0, 700.0,   0.0,  // išorės apsauga
                   700.0,   0.0, 700.0, 500.0,
                   700.0, 500.0,   0.0, 500.0,
                     0.0, 500.0,   0.0,   0.0,

                    83.0,  79.0, 329.0,  79.0, // ilgosios sienos
                   370.0,  79.0, 615.0,  79.0,
                   640.0, 105.0, 640.0, 346.0,
                   615.0, 371.0, 370.0, 371.0,
                   329.0, 371.0,  83.0, 371.0,
                    59.0, 346.0,  59.0, 105.0,

                   329.0,  79.0, 334.0,  67.0, // vidurinė kišenė
                   334.0,  67.0, 335.0,  58.0,
                   335.0,  58.0, 340.0,  51.0,
                   340.0,  51.0, 350.0,  48.0,
                   350.0,  48.0, 359.0,  51.0,
                   359.0,  51.0, 364.0,  58.0,
                   364.0,  58.0, 365.0,  67.0,
                   365.0,  67.0, 370.0,  79.0, // vidurinės kišenės pabaiga

                   615.0,  79.0, 630.0,  66.0,  // kitos kišėnės
                   630.0,  66.0, 640.0,  54.0,
                   640.0,  54.0, 655.0,  54.0,
                   655.0,  54.0, 666.0,  65.0,
                   666.0,  65.0, 666.0,  80.0,
                   666.0,  80.0, 653.0,  90.0,
                   653.0,  90.0, 640.0, 105.0,

                   640.0, 346.0, 654.0, 361.0,
                   654.0, 361.0, 666.0, 371.0,
                   666.0, 371.0, 666.0, 387.0,
                   666.0, 387.0, 655.0, 397.0,
                   655.0, 397.0, 640.0, 397.0,
                   640.0, 397.0, 629.0, 384.0,
                   629.0, 384.0, 615.0, 371.0,

                   370.0, 371.0, 365.0, 382.0,
                   365.0, 382.0, 364.0, 393.0,
                   364.0, 393.0, 357.0, 401.0,
                   357.0, 401.0, 348.0, 403.0,
                   348.0, 403.0, 338.0, 399.0,
                   338.0, 399.0, 333.0, 389.0,
                   333.0, 389.0, 332.0, 381.0,
                   332.0, 381.0, 328.0, 371.0,

                    83.0, 371.0,  68.0, 384.0,
                    68.0, 384.0,  60.0, 396.0,
                    60.0, 396.0,  43.0, 397.0,
                    43.0, 397.0,  32.0, 385.0,
                    32.0, 385.0,  33.0, 370.0,
                    33.0, 370.0,  46.0, 359.0,
                    46.0, 359.0,  59.0, 346.0,
                    59.0, 105.0,  46.0,  91.0,
                    46.0,  91.0,  32.0,  78.0,
                    32.0,  78.0,  33.0,  63.0,
                    33.0,  63.0,  44.0,  53.0,
                    44.0,  53.0,  57.0,  53.0,
                    57.0,  53.0,  69.0,  67.0,
                    69.0,  67.0,  83.0,  80.0,
                 };
    int ns = sizeof(s)/sizeof(double)/4;
    splines.clear();
    TSpline sp = {CVect2d(0.0, 0.0), CVect2d(0.0, 0.0)};
    for ( int i = 0; i < ns; i++ ) {
        sp.p1.set( s[i*4], s[i*4+1] ); sp.p2.set( s[i*4+2], s[i*4+3] ); splines.append(sp);
    }

    // kišenių sąrašas
    holes.clear();
    TBall hl = { CVect2d(0.0, 0.0), CVect2d(0.0, 0.0), 9, 255, 255, 255, false, 0, -1 };
    hl.pos.set( 655.0, 65.0 ); hl.radius = 15.0; holes.append(hl);
    hl.pos.set( 350.0, 55.0 ); hl.radius = 14.0; holes.append(hl);
    hl.pos.set( 655.0, 385.0 ); hl.radius = 15.0; holes.append(hl);
    hl.pos.set( 350.0, 395.0 ); hl.radius = 14.0; holes.append(hl);
    hl.pos.set( 45.0, 385.0 ); hl.radius = 15.0; holes.append(hl);
    hl.pos.set( 45.0, 65.0 ); hl.radius = 15.0; holes.append(hl);

    // nustatoma kad žaidimo tipas dar nėra nustatytas
    gameType = -1;
    players = -1;

    for ( int i = 0; i < 16; i++ )
        sm->getSound()->play( "audio/opr000L0-14.mp3", 0.0 );

}

void CTestScreen::unload(CGraphics *gl)
{
    CScreen* b = sm->getScreen("backgroundScreen");
    if ( b != 0 ) b->setHidden( false );

    sm->getSound()->clear();

    gl->deleteTexture( textures[0] );
    gl->deleteTexture( textures[1] );
    gl->deleteTexture( textures[2] );
    gl->deleteTexture( textures[3] );
    gl->deleteTexture( textures[4] );
    gl->deleteTexture( textures[5] );
    gl->deleteTexture( textures[6] );
    gl->deleteTexture( textures[7] );
    gl->deleteTexture( textures[8] );
    gl->deleteTexture( textures[9] );
    gl->deleteTexture( textures[10] );
}

void rotate( CVect3d &p, CVect3d &p2, const CVect2d &moove )
{
    double nx = -moove.getY(),
           ny = moove.getX();
    double m = sqrt( nx*nx + ny*ny );
    if ( m == 0.0 ) m = 0.00000001;
    nx /= m;
    ny /= m;

    CVect3d axis( nx, 0.0, ny );
    double angle = m/9.0;

    double M[9];    // rotation matrix
    double q0 = cos(angle/2.0);
    double q1 = sin(angle/2.0)*axis.getX();
    double q2 = sin(angle/2.0)*axis.getY();
    double q3 = sin(angle/2.0)*axis.getZ();
    double q02 = q0*q0;
    double q12 = q1*q1;
    double q22 = q2*q2;
    double q32 = q3*q3;

    M[0] = q02 + q12 - q22 - q32;
    M[1] = 2*( q1*q2 - q0*q3 );
    M[2] = 2*( q1*q3 + q0*q2 );
    M[3] = 2*( q2*q1 + q0*q3 );
    M[4] = q02 - q12 + q2 - q32;
    M[5] = 2*( q2*q3 - q0*q1 );
    M[6] = 2*( q3*q1 - q0*q2 );
    M[7] = 2*( q3*q2 + q0*q1 );
    M[8] = q02 - q12 - q22 + q32;

    double x, y, z;

    x = p.getX()*M[0] + p.getY()*M[3] + p.getZ()*M[6];
    y = p.getX()*M[1] + p.getY()*M[4] + p.getZ()*M[7];
    z = p.getX()*M[2] + p.getY()*M[5] + p.getZ()*M[8];
    p.set( x, y, z );

    x = p2.getX()*M[0] + p2.getY()*M[3] + p2.getZ()*M[6];
    y = p2.getX()*M[1] + p2.getY()*M[4] + p2.getZ()*M[7];
    z = p2.getX()*M[2] + p2.getY()*M[5] + p2.getZ()*M[8];
    p2.set( x, y, z );
}

// atlieka pagrindinius logikos veiksmus
// return - grąžina 0 jei kamuoliukai vis dar juda, 1 jei visi neimušti sustoję
int CTestScreen::doLogic( const double &frameTime )
{
    double timeLeft = frameTime;
    double maxSpeed = 0.0;

    for ( int i = 0; i < balls.size(); i++ ) {
        if ( balls[i].status == -1 ) continue;
        if ( -1 < balls[i].status && balls[i].status < 6 ) {
            double speed = balls[i].speed.lenght();
            if ( speed < 30.0 ) speed = 30.0;
            if ( speed > 150.0 ) speed = 150.0;
            balls[i].speed = (holes[balls[i].status].pos - balls[i].pos).direction() * speed;
            if ( (holes[balls[i].status].pos - balls[i].pos).lenght() < 10 )
                balls[i].status = 6;
        } else if ( balls[i].status == 6 ) {
            balls[i].speed = (CVect2d(350.0, 250.0) - balls[i].pos).direction() * balls[i].speed.lenght();
            if ( (CVect2d(350.0, 225.0) - balls[i].pos).lenght() < 120.0 ) {
                balls[i].status = 7;
                balls[i].speed.set( 0.0, 0.0 );
            }
        }
    }

    for ( int i = 0; i < balls.size(); i++ ) {
        if ( balls[i].status > 5 ) continue;
        double speed = balls[i].speed.lenght();
        if ( speed == 0.0 ) continue;
        if ( speed < 2.0 ) {
            balls[i].speed.set( 0.0, 0.0 );
            continue;
        } else if ( speed < 40.0 ) {
            balls[i].speed *= 0.98;
        } else {
            balls[i].speed *= 0.99;
        }
        if ( speed > maxSpeed )
            maxSpeed = speed;
    }
    while ( timeLeft >= 0.000001 ) {
        int obj = -1, obj2 = -1;
        int type = -1;
        double time = -1.0;
        for ( int i = 0; i < balls.size(); i++ ) {
            if ( balls[i].inHole ) continue;
            double speed = balls[i].speed.lenght();
            if ( speed == 0.0 ) continue;
            for ( int j = 0; j < splines.size(); j++ ) {
                double dis = circleDisToSpline( balls[i].pos, balls[i].radius, balls[i].speed.direction(), splines[j].p1, splines[j].p2 );
                if ( dis != -1.0 && dis > 0.00001 ) {
                    double t = dis / speed;
                    if ( time == -1.0 || t < time ) {
                        obj = i; obj2 = j; type = 1;
                        time = t;
                    }
                }
            }
            for ( int j = 0; j < balls.size(); j++ ) {
                if ( j == i ) continue;
                if ( balls[j].inHole ) continue;
                if ( i > j && ( balls[j].speed.getX() != 0 || balls[j].speed.getY() != 0 ) )
                    continue;
                double t = circleToMovingCircle( balls[i].pos, balls[j].pos, balls[i].speed, balls[j].speed, balls[i].radius, balls[j].radius );
                if ( t != -1.0 && ( time == -1.0 || t < time ) ) {
                    obj = i; obj2 = j; type = 2;
                    time = t;
                }
            }
            for ( int j = 0; j < holes.size(); j++ ) {
                double t = circleToMovingCircle( balls[i].pos, holes[j].pos, balls[i].speed, holes[j].speed, balls[i].radius, holes[j].radius );
                if ( t != -1.0 && ( time == -1.0 || t < time ) ) {
                    obj = i; obj2 = j; type = 3;
                    time = t;
                }
            }
        }

        if ( type == -1 || time > timeLeft-0.000000001 ) { // susidurimų nerasta :D || susidurimai ne šiame frame
            for ( int i = 0; i < balls.size(); i++ ) {
//                if ( balls[i].inHole ) continue;
                balls[i].pos = balls[i].pos + balls[i].speed*timeLeft;
                rotate( balls[i].p, balls[i].p2, balls[i].speed*timeLeft );
            }
            timeLeft = 0.0;
        } else {    // BUM!!!!!!!!
            time = time - 0.0000000001;
            for ( int i = 0; i < balls.size(); i++ ) {
//                if ( balls[i].inHole ) continue;
                balls[i].pos = balls[i].pos + balls[i].speed*time;
                rotate( balls[i].p, balls[i].p2, balls[i].speed*time );
            }
            if ( type == 1 ) { // ball vs spline
                CVect2d collidePoint = circleCPOnSpline( balls[obj].pos, balls[obj].radius, balls[obj].speed.direction(), splines[obj2].p1, splines[obj2].p2 );
                CVect2d hitVect = balls[obj].pos - collidePoint;
                CVect2d bounce = balls[obj].speed.projectionTo(hitVect) * -1.0;
                CVect2d slide = balls[obj].speed.projectionTo(hitVect.leftNormal());
                double friction = 0.02;
                double bounciness = 0.8;
                balls[obj].speed = bounce * bounciness + slide * ( 1 - friction );
                touchedSpline = true;
                sm->getSound()->play("audio/opr000L0-18.mp3");
//                balls[obj].speed = bounce + slide;
            } else if ( type == 2 ) { // ball vs ball
                sm->getSound()->play("audio/opr000L0-14.mp3");
                CVect2d dir = (balls[obj].pos-balls[obj2].pos).direction();
                CVect2d as = balls[obj].speed, bs = balls[obj2].speed;
                balls[obj].speed = as.projectionTo(dir.leftNormal()) + bs.projectionTo(dir);
                balls[obj2].speed = bs.projectionTo(dir.rightNormal()) + as.projectionTo(dir);
                if ( firstHitBall == -1 )
                    firstHitBall = balls[obj2].number;
            } else if ( type == 3 ) {
                sm->getSound()->play("audio/opr000L0-15.mp3");
                balls[obj].inHole = true;
                balls[obj].status = obj2;
                pocketedBalls.append( balls[obj].number );
            }
            timeLeft = timeLeft - time;
        }
    }

    if ( maxSpeed == 0 )
        return 1;
    else
        return 0;
}

void CTestScreen::findFirstCollision()
{
    double dis = -1.0; int type = -1, obj2 = -1;
    bounceBall = -1;
    for ( int i = 0; i < splines.size(); i++ ) {
        double d = circleDisToSpline( balls[0].pos, balls[0].radius, hitDirection, splines[i].p1, splines[i].p2 );
        if ( d != -1.0 && ( dis == -1.0 || d < dis ) ) {
                dis = d; obj2 = i; type = 0;
        }
    }
    for ( int i = 1; i < balls.size(); i++ ) {
        if ( balls[i].status != -1 ) continue;
        double d = circleToMovingCircle( balls[0].pos, balls[i].pos, hitDirection, balls[i].speed, balls[0].radius, balls[i].radius );
        if ( d != -1.0 && ( dis == -1.0 || d < dis ) ) {
                dis = d; obj2 = i; type = 1;
        }
    }
    if ( dis != -1.0 ) {
        dis = dis - 0.000001;
        collidePos = balls[0].pos + hitDirection * dis;
        if ( type == 0 ) {
            CVect2d collidePoint = circleCPOnSpline( balls[0].pos, balls[0].radius, hitDirection, splines[obj2].p1, splines[obj2].p2 );
            CVect2d hitVect = collidePos - collidePoint;
            CVect2d bounce = hitDirection.projectionTo(hitVect) * -1.0;
            CVect2d slide = hitDirection.projectionTo(hitVect.leftNormal());
            double friction = 0.02;
            double bounciness = 0.8;
            bounceDir = bounce * bounciness + slide * ( 1 - friction );
        } else if ( type == 1 ) {
            CVect2d dir = (collidePos-balls[obj2].pos).direction();
            CVect2d as = hitDirection, bs = CVect2d( 0.0, 0.0 );
            bounceDir = as.projectionTo(dir.leftNormal()) + bs.projectionTo(dir);
            bounceDir2 = (bs.projectionTo(dir.rightNormal()) + as.projectionTo(dir)) * 25.0;
            bounceBall = obj2;
        }
    }
}

// 8 Ball logika
int CTestScreen::update8Ball( CInput *in, const double &frameTime )
{

    if ( gameState == 0 ) { // taikymas
        hitDirection = (CVect2d( in->getCursorPos().x(), in->getCursorPos().y() ) - balls[0].pos).direction();
        findFirstCollision();
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
            gameState = 1;
            hitPoint = CVect2d( in->getCursorPos().x(), in->getCursorPos().y() );
        }
    } else if ( gameState == 1 ) {
        hitForce = pointDisToLine( CVect2d( in->getCursorPos().x(), in->getCursorPos().y()), hitPoint, hitPoint+hitDirection.rightNormal() );
        if ( hitForce < 0.0 ) hitForce = 0.0;
        if ( hitForce > 50.0 ) hitForce = 50.0;
        if ( in->wasButtonReleased(Qt::LeftButton) ) {
            if ( hitForce != 0.0 ) {
                balls[0].speed = hitDirection.direction() * hitForce * 20.0;
                gameState = 2;
                hitForce = 0;
            } else {
                gameState = 0;
            }
        }
    } else if ( gameState == 2 ) {        
        if ( doLogic( frameTime ) == 1 ) {  // jei kamuoliukai nejuda

            bool changePlayer = false;
            gameState = 0;

            if ( firstHitBall == -1 ||
                 (firstHitBall == 8 && ballsLeft[playersTurn] > 1) ||
                 (stripedPlayer != 0 &&
                  (((firstHitBall > 8) && (playersTurn != stripedPlayer)) ||
                  (((firstHitBall > 0) && (firstHitBall < 8) && (stripedPlayer == playersTurn)) ))
                 )) {
                changePlayer = true;
                gameState = 3;
            }
            if ( pocketedBalls.size() == 0 ) {  // jei nebuvo imuštas joks kamuoliukas
                changePlayer = true;
            } else {
                foreach ( int b, pocketedBalls ) {
                    if ( b == 0 ) {
                        balls[0].inHole = false;
                        balls[0].status = -1;
                        gameState = 4;
                        changePlayer = true;
                    } else if ( b != 8 ) {  // spalvoti kamuoliukai
                        if ( stripedPlayer == 0 ) {
                            if ( (b > 8 && playersTurn == 1) || (b < 8 && playersTurn == 2) )
                                stripedPlayer = 1;
                            else stripedPlayer = 2;
                        }
                        if ( b > 8 )
                            ballsLeft[stripedPlayer]--;
                        else
                            ballsLeft[(stripedPlayer==1)?2:1]--;
                    } else {    // įmuštas juodas kamuoliukas
                        if ( ballsLeft[playersTurn] > 1 || pocketedBalls.contains(0) ) {
                            winner = ((playersTurn==1)?2:1);
                        } else {
                            winner = playersTurn;
                        }
                        gameState = 5;
                    }
                }
                pocketedBalls.clear();
            }
            if ( changePlayer )
                playersTurn = (playersTurn==1)?2:1;
            firstHitBall = -1;

            if ( gameState == 0 ) {
                if ( playersTurn == 1 ) status = QString::fromStdWString(L"Muša pirmasis žaidėjas");
                else                    status = QString::fromStdWString(L"Muša antrasis žaidėjas");
            } else if ( gameState == 3 ) {
                if ( playersTurn == 1 ) status = QString::fromStdWString(L"Klaida! pirmasis žaidėjas stato kamuoliuką namų zonoje");
                else                    status = QString::fromStdWString(L"Klaida! antrasis žaidėjas stato kamuoliuką namų zonoje");
            } else if ( gameState == 4 ) {
                if ( playersTurn == 1 ) status = QString::fromStdWString(L"Klaida! pirmasis žaidėjas stato kamuoliuką");
                else                    status = QString::fromStdWString(L"Klaida! antrasis žaidėjas stato kamuoliuką");
            } else if ( gameState == 5 ) {
                if ( winner == 1 ) status = QString::fromStdWString(L"Laimėjo pirmasis žaidėjas!");
                else               status = QString::fromStdWString(L"Laimėjo antrasis žaidėjas!");
            }

        }

    } else if ( gameState == 3 ) {  // kamuoliuko pastatymas namų zonoje
        double x = in->getCursorPos().x();
        double y = in->getCursorPos().y();
        if ( x < 60+balls[0].radius ) x = 60+balls[0].radius;
        if ( y < 80+balls[0].radius ) y = 80+balls[0].radius;
        if ( y > 370-balls[0].radius ) y = 370-balls[0].radius;
        if ( x > 250-balls[0].radius ) x = 250-balls[0].radius;
        bool safe = true;
        for ( int i = 1; i < balls.size(); i++ ) {
            if ( collide( CVect2d(x,y), balls[i].pos, balls[0].radius, balls[i].radius) ) {
                safe = false;
                break;
            }
        }
        if ( safe )
            balls[0].pos.set( x, y );
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
            gameState = 0;            
            if ( playersTurn == 1 ) status = QString::fromStdWString(L"Muša pirmasis žaidėjas");
            else                    status = QString::fromStdWString(L"Muša antrasis žaidėjas");
        }
    } else if ( gameState == 4 ) {  // kamuoliuko pastatymas betkur
        double x = in->getCursorPos().x();
        double y = in->getCursorPos().y();
        if ( x < 60+balls[0].radius ) x = 60+balls[0].radius;
        if ( y < 80+balls[0].radius ) y = 80+balls[0].radius;
        if ( y > 370-balls[0].radius ) y = 370-balls[0].radius;
        if ( x > 640-balls[0].radius ) x = 640-balls[0].radius;
        bool safe = true;
        for ( int i = 1; i < balls.size(); i++ ) {
            if ( collide( CVect2d(x,y), balls[i].pos, balls[0].radius, balls[i].radius) ) {
                safe = false;
                break;
            }
        }
        if ( safe )
            balls[0].pos.set( x, y );
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
                gameState = 0;
            if ( playersTurn == 1 ) status = QString::fromStdWString(L"Muša pirmasis žaidėjas");
            else                    status = QString::fromStdWString(L"Muša antrasis žaidėjas");
        }
    } else if ( gameState == 5 ) {  // žaidimo pabaiga, laimi kažkas
        if ( in->wasKeyPressed(Qt::Key_Return) )
            this->setGameSettings( 0, 0 );
    }

    return 0;
}

int CTestScreen::update9Ball( CInput *in, const double &frameTime ) {

    if ( gameState == 0 ) { // taikymas
        hitDirection = (CVect2d( in->getCursorPos().x(), in->getCursorPos().y() ) - balls[0].pos).direction();
        findFirstCollision();
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
            gameState = 1;
            hitPoint = CVect2d( in->getCursorPos().x(), in->getCursorPos().y() );
        }
    } else if ( gameState == 1 ) {
        hitForce = pointDisToLine( CVect2d( in->getCursorPos().x(), in->getCursorPos().y()), hitPoint, hitPoint+hitDirection.rightNormal() );
        if ( hitForce < 0.0 ) hitForce = 0.0;
        if ( hitForce > 50.0 ) hitForce = 50.0;
        if ( in->wasButtonReleased(Qt::LeftButton) ) {
            if ( hitForce != 0.0 ) {
                balls[0].speed = hitDirection.direction() * hitForce * 20.0;
                gameState = 2;
                hitForce = 0;
            } else {
                gameState = 0;
            }
        }
    } else if ( gameState == 2 ) {
        if ( doLogic( frameTime ) == 1 ) {  // jei kamuoliukai nejuda

            gameState = 0;
            bool changePlayer = false;
            bool foul = false;
            bool result = false;

            if ( lowestBall != firstHitBall )
                foul = true;
            if ( pocketedBalls.size() > 0 && !pocketedBalls.contains( 0 ) )
                result = true;

            if ( pocketedBalls.contains(0) ) {
                balls[0].inHole = false;
                balls[0].status = -1;
                gameState = 4;
                changePlayer = true;
            }

            if ( !result || foul )
                changePlayer = true;

            if ( foul )
                gameState = 4;

            if ( changePlayer )
                playersTurn = (playersTurn==1)?2:1;

            if ( !foul && pocketedBalls.contains(9) ) {
                winner = playersTurn;
                gameState = 5;
            }
            if ( foul && pocketedBalls.contains(9) ) {
                balls[9].inHole = false;
                balls[9].status = -1;
                balls[9].pos.set( 523.0, 225.0 );
            }

            for ( int i = 1; i < 10; i++ ) {
                if ( balls[i].status == -1 ) {
                    lowestBall = i;
                    break;
                }
            }

            touchedSpline = false;
            firstHitBall = -1;
            pocketedBalls.clear();

            if ( gameState == 0 ) {
                if ( playersTurn == 1 ) status = QString::fromStdWString(L"Muša pirmasis žaidėjas");
                else                    status = QString::fromStdWString(L"Muša antrasis žaidėjas");
            } else if ( gameState == 4 ) {
                if ( playersTurn == 1 ) status = QString::fromStdWString(L"Klaida! pirmasis žaidėjas stato kamuoliuką");
                else                    status = QString::fromStdWString(L"Klaida! antrasis žaidėjas stato kamuoliuką");
            } else if ( gameState == 5 ) {
                if ( winner == 1 ) status = QString::fromStdWString(L"Laimėjo pirmasis žaidėjas!");
                else               status = QString::fromStdWString(L"Laimėjo antrasis žaidėjas!");
            }


        }

    } else if ( gameState == 3 ) {  // kamuoliuko pastatymas namų zonoje
        gameState = 4;
    } else if ( gameState == 4 ) {  // kamuoliuko pastatymas betkur
        double x = in->getCursorPos().x();
        double y = in->getCursorPos().y();
        if ( x < 60+balls[0].radius ) x = 60+balls[0].radius;
        if ( y < 80+balls[0].radius ) y = 80+balls[0].radius;
        if ( y > 370-balls[0].radius ) y = 370-balls[0].radius;
        if ( x > 640-balls[0].radius ) x = 640-balls[0].radius;
        bool safe = true;
        for ( int i = 1; i < balls.size(); i++ ) {
            if ( collide( CVect2d(x,y), balls[i].pos, balls[0].radius, balls[i].radius) ) {
                safe = false;
                break;
            }
        }
        if ( safe )
            balls[0].pos.set( x, y );
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
                gameState = 0;
            if ( playersTurn == 1 ) status = QString::fromStdWString(L"Muša pirmasis žaidėjas");
            else                    status = QString::fromStdWString(L"Muša antrasis žaidėjas");
        }
    } else if ( gameState == 5 ) {  // žaidimo pabaiga, laimi kažkas
        if ( in->wasKeyPressed(Qt::Key_Return) )
            this->setGameSettings( 1, 0 );
    }

    return 0;
}

int CTestScreen::updateQuickPool( CInput *in, const double &frameTime ) {

    timeLeft -= frameTime;

    if ( timeLeft < 0.0 ) {
        timeLeft = 0.0;
        gameState = 5;
    }

    if ( gameState == 0 ) { // taikymas
        hitDirection = (CVect2d( in->getCursorPos().x(), in->getCursorPos().y() ) - balls[0].pos).direction();
        findFirstCollision();
        if ( in->wasButtonPressed(Qt::LeftButton) ) {
            gameState = 1;
            hitPoint = CVect2d( in->getCursorPos().x(), in->getCursorPos().y() );
        }
    } else if ( gameState == 1 ) {
        hitForce = pointDisToLine( CVect2d( in->getCursorPos().x(), in->getCursorPos().y()), hitPoint, hitPoint+hitDirection.rightNormal() );
        if ( hitForce < 0.0 ) hitForce = 0.0;
        if ( hitForce > 50.0 ) hitForce = 50.0;
        if ( in->wasButtonReleased(Qt::LeftButton) ) {
            if ( hitForce != 0.0 ) {
                balls[0].speed = hitDirection.direction() * hitForce * 20.0;
                gameState = 2;
                hitForce = 0;
            } else {
                gameState = 0;
            }
        }
    } else if ( gameState == 2 ) {
        if ( doLogic( frameTime ) == 1 ) {  // jei kamuoliukai nejuda

            gameState = 0;

            if ( pocketedBalls.contains(0) ) {
                balls[0].inHole = false;
                balls[0].status = -1;
                gameState = 4;
                timeLeft -= 30.0;
            }

            int ballsLeft = 0;
            for ( int i = 1; i < balls.size(); i++ )
                if ( balls[i].status < 6 )
                    ballsLeft++;

            if ( ballsLeft < 2 ) {                
                sm->getSound()->play("audio/opr000L0-13.mp3");

                int ballLeft = -1;
                for ( int i = 1; i < balls.size(); i++ )
                    if ( balls[i].status == -1 )
                        ballLeft = i;
                double pos[] = { 203.0, 225.0, 553.0, 245.0, 508.0, 235.0, 538.0, 195.0,
                                 508.0, 215.0, 553.0, 265.0, 523.0, 245.0, 553.0, 205.0,
                                 523.0, 225.0, 493.0, 225.0, 523.0, 205.0, 538.0, 215.0,
                                 553.0, 225.0, 553.0, 185.0, 538.0, 235.0, 538.0, 255.0, };
                for ( int i = 1; i < balls.size(); i++ ) {
                    if ( balls[i].status > 5 ) {
                        balls[i].status = -1;
                        balls[i].inHole = false;
                        balls[i].speed.set( 0.0, 0.0 );
                        balls[i].pos.set( pos[2*i], pos[2*i+1] );
                    }
                }
                for ( int i = 1; i < balls.size(); i++ ) {
                    if ( collide( balls[0].pos, balls[i].pos, balls[0].radius, balls[i].radius ) ) {
                        balls[0].pos.set( 203.0, 225.0 );
                        break;
                    }
                }
                if ( ballLeft != -1 ) {
                    for ( int i = 1; i < balls.size(); i++ ) {
                        if ( ballLeft == i ) continue;
                        if ( collide( balls[ballLeft].pos, balls[i].pos, balls[ballLeft].radius, balls[i].radius ) ) {
                            balls[ballLeft].pos.set( pos[2*ballLeft], pos[2*ballLeft+1] );
                            break;
                        }
                    }
                }
            }


            firstHitBall = -1;
            pocketedBalls.clear();

        } else {
            for ( int i = pocketedBalls.size()-1; i >= 0; i-- ) {
                if ( pocketedBalls[i] != 0 ) {
                    points += 100;
                    timeLeft += 5.0;
                    pocketedBalls.removeAll(pocketedBalls[i]);
                }
            }
        }
    } else if ( gameState == 4 ) {
        double x = in->getCursorPos().x();
        double y = in->getCursorPos().y();
        if ( x < 60+balls[0].radius ) x = 60+balls[0].radius;
        if ( y < 80+balls[0].radius ) y = 80+balls[0].radius;
        if ( y > 370-balls[0].radius ) y = 370-balls[0].radius;
        if ( x > 640-balls[0].radius ) x = 640-balls[0].radius;
        bool safe = true;
        for ( int i = 1; i < balls.size(); i++ ) {
            if ( collide( CVect2d(x,y), balls[i].pos, balls[0].radius, balls[i].radius) ) {
                safe = false;
                break;
            }
        }
        if ( safe )
            balls[0].pos.set( x, y );
        if ( in->wasButtonPressed(Qt::LeftButton) )
                gameState = 0;
    } else if ( gameState == 5 ) {
        doLogic( frameTime );
        if ( in->wasKeyPressed(Qt::Key_Return) )
            this->setGameSettings( 2, 0 );
    }

    return 0;
}

int CTestScreen::update(CInput *in)
{
    // TODO screen lost focus or Key_Escape -> pauzė
    if ( in->wasKeyPressed(Qt::Key_Escape) || in->hasScreenLostFocus() ) {
        sm->addScreen( new CGamePauseScreen("gamePauseScreen") );
    }

    if ( in->wasKeyPressed( Qt::Key_Space ) )
        sm->getSound()->clear();

    double frameTime = 0.016;

    if ( gameType == 0 ) {  // 8 Ball
        update8Ball( in, frameTime );
    } else if ( gameType == 1 ) { // 9 Ball
        update9Ball( in, frameTime );
    } else if ( gameType == 2 ) { // žaidimo tipas nenustatytas
        updateQuickPool( in, frameTime );
    }

    return 0;
}

void drawLine( const CGraphics* gl, const CVect2d &p1, const CVect2d &p2, int r, int g, int b, int a )
{
    glColor4f( r/255.0f, g/255.0f, b/255.0f, a/255.0f );
    glDisable( GL_TEXTURE_2D );
    glBegin( GL_LINES );
        glVertex2f( p1.getX(), p1.getY() );
        glVertex2f( p2.getX(), p2.getY() );
    glEnd();
    glEnable( GL_TEXTURE_2D );
}

void drawArrow( const CGraphics* gl, const CVect2d &org, const CVect2d &dir, int r, int g, int b, int a )
{
    CVect2d p1, p2;
    if ( (org - dir).lenght() == 0 )
        return;
    p1 = (org - dir).direction() * 5;
    p2 = dir + p1.leftNormal() + p1;
    p1 = dir + p1.rightNormal() + p1;
    drawLine( gl, org, dir, r, g, b, a );
    drawLine( gl, dir, p1, r, g, b, a );
    drawLine( gl, dir, p2, r, g, b, a );
}

void drawCircle( const CGraphics* gl, const CVect2d &pos, const int &radius, int r, int g, int b, int a  )
{
    glColor4f( r/255.0f, g/255.0f, b/255.0f, a/255.0f );
    glDisable( GL_TEXTURE_2D );
    glBegin( GL_LINE_LOOP );
        int rounding = 60;
        for ( int i = 1; i <= rounding; i++ ) {
            glVertex2f( pos.getX() + sin(6.28318*i/rounding)*radius,
                         pos.getY() - cos(6.28318*i/rounding)*radius );
        }
    glEnd();
    glEnable( GL_TEXTURE_2D );
}

void CTestScreen::drawBall( CGraphics *gl, const TBall &b )
{
    int num = b.number;
    if ( num < 0 || num > 15 )
        num = 0;

    double mx = b.p.getX(), my = b.p.getZ();
    double m = sqrt( mx*mx + my*my );
    if ( m == 0.0 ) m = 0.000000001;
    double mx2 = b.p2.getX(), my2 = b.p2.getZ();
    double m2 = sqrt( mx2*mx2 + my2*my2 );
    if ( m2 == 0.0 ) m2 = 0.000000001;

    glPushMatrix();
    glLoadIdentity();
    glTranslatef( b.pos.getX(), b.pos.getY(), 0.0f );

    if ( num > 0 ) {
        glColorMask( 0, 0, 0, 0 );

        glEnable( GL_STENCIL_TEST );
        glStencilFunc( GL_ALWAYS, 1, 1 );
        glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );

        if ( num > 8 ) { // striped balls white spots
            if ( b.p.getY() > -0.2 ) {
                glPushMatrix();
                double angle = asin( my/m )*180.f/3.14259265f;
                if ( mx<0.0 ) angle = 180-angle;
                glRotatef( angle, 0.0f, 0.0f, 1.0f );
                glTranslatef( m*10.0f, 0.0f, 0.0f );
                glScalef( sqrt(fabs(b.p.getY()+0.2)), 1.0f, 1.0f );
                glBindTexture( GL_TEXTURE_2D, textures[8] ); // mask
                glBegin(GL_QUADS);
                    glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -7.5f, 7.5f );
                    glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -7.5f, -7.5f );
                    glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 7.5f, -7.5f );
                    glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 7.5f, 7.5f );
                glEnd();
                glPopMatrix();
            }
            if ( b.p.getY() < 0.2 ) {
                glPushMatrix();
                double angle = -asin( my/m )*180.f/3.14259265f;
                if ( mx>0.0 ) angle = 180-angle;
                glRotatef( angle, 0.0f, 0.0f, 1.0f );
                glTranslatef( m*10.0f, 0.0f, 0.0f );
                glScalef( sqrt(fabs(b.p.getY()-0.2)), 1.0f, 1.0f );
                glBindTexture( GL_TEXTURE_2D, textures[8] ); // mask
                glBegin(GL_QUADS);
                    glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -7.5f, 7.5f );
                    glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -7.5f, -7.5f );
                    glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 7.5f, -7.5f );
                    glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 7.5f, 7.5f );
                glEnd();
                glPopMatrix();
            }
        }

        if ( b.p2.getY() < 0.1 ) {
            glPushMatrix();
            double angle = -asin( my2/m2 )*180.f/3.14259265f;
            if ( mx2>0.0 ) angle = 180-angle;
            glRotatef( angle, 0.0f, 0.0f, 1.0f );
            glTranslatef( m2*10.0f, 0.0f, 0.0f );
            glScalef( sqrt(fabs(b.p2.getY()-0.1)), 1.0f, 1.0f );
            glBindTexture( GL_TEXTURE_2D, textures[8] ); // mask
            glBegin(GL_QUADS);
                glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -5.0f, 5.0f );
                glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -5.0f, -5.0f );
                glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 5.0f, -5.0f );
                glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 5.0f, 5.0f );
            glEnd();
            glPopMatrix();
        }
        if ( b.p2.getY() > -0.1 ) {
            glPushMatrix();
            double angle = asin( my2/m2 )*180.f/3.14259265f;
            if ( mx2<0.0 ) angle = 180-angle;
            glRotatef( angle, 0.0f, 0.0f, 1.0f );
            glTranslatef( m2*10.0f, 0.0f, 0.0f );
            glScalef( sqrt(fabs(b.p2.getY()+0.1)), 1.0f, 1.0f );
            glBindTexture( GL_TEXTURE_2D, textures[8] ); // mask
            glBegin(GL_QUADS);
                glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -5.0f, 5.0f );
                glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -5.0f, -5.0f );
                glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 5.0f, -5.0f );
                glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 5.0f, 5.0f );
            glEnd();
            glPopMatrix();
        }

        glColorMask( 1, 1, 1, 1 );

        glStencilFunc( GL_NOTEQUAL, 1, 1 );
        glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );

        glColor4f( b.r, b.g, b.b, 1.0f );
        glBindTexture( GL_TEXTURE_2D, textures[4] ); // coloured ball
        glBegin(GL_QUADS);
            glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -12.0f, 13.0f );
            glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -12.0f, -11.0f );
            glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 12.0f, -11.0f );
            glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 12.0f, 13.0f );
        glEnd();

        glStencilFunc( GL_EQUAL, 1, 1 );
    }
/**/
    glColor3f( 1.0f, 1.0f, 1.0f );
    glBindTexture( GL_TEXTURE_2D, textures[4] ); // white ball
    glBegin(GL_QUADS);
        glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -12.0f, 13.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -12.0f, -11.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 12.0f, -11.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 12.0f, 13.0f );
    glEnd();

    if ( num > 0 ) {
        glClear( GL_STENCIL_BUFFER_BIT );
        glDisable( GL_STENCIL_TEST );
    }

    if ( num > 0 ) { // number

        glColorMask( 0, 0, 0, 0 );
        glEnable( GL_STENCIL_TEST );
        glStencilFunc( GL_ALWAYS, 1, 1 );
        glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );

        glColor3f( 1.0f, 1.0f, 1.0f );
        glBindTexture( GL_TEXTURE_2D, textures[8] ); // mask
        glBegin(GL_QUADS);
            glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -9.0f, -9.0f );
            glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -9.0f, 9.0f );
            glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 9.0f, 9.0f );
            glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 9.0f, -9.0f );
        glEnd();

        glColorMask( 1, 1, 1, 1 );
        glStencilFunc( GL_EQUAL, 1, 1 );
        glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );

        if ( b.p2.getY() < 0.1 ) {
            glPushMatrix();
            double angle = -asin( my2/m2 )*180.f/3.14259265f;
            if ( mx2>0.0 ) angle = 180-angle;
            glRotatef( angle, 0.0f, 0.0f, 1.0f );
            glTranslatef( m2*10.0f, 0.0f, 0.0f );
            glScalef( sqrt(fabs(b.p2.getY()-0.1)), 1.0f, 1.0f );
            double angle2 = -asin( my/m )*180.f/3.14259265f;
            if ( mx>0.0 ) angle2 = 180-angle2;
            glRotatef( -angle+angle2+90.0f, 0.0f, 0.0f, 1.0f );
            glBindTexture( GL_TEXTURE_2D, textures[7] ); // number
            glBegin(GL_QUADS);
                glTexCoord2f( 0.0f, (16-num)/15.0f ); glVertex2f( -5.0f, -5.0f );
                glTexCoord2f( 0.0f, (15-num)/15.0f ); glVertex2f( -5.0f, 5.0f );
                glTexCoord2f( 1.0f, (15-num)/15.0f ); glVertex2f( 5.0f, 5.0f );
                glTexCoord2f( 1.0f, (16-num)/15.0f ); glVertex2f( 5.0f, -5.0f );
            glEnd();
            glPopMatrix();
        }
        if ( b.p2.getY() > -0.1 ) {
            glPushMatrix();
            double angle = asin( my2/m2 )*180.f/3.14259265f;
            if ( mx2<0.0 ) angle = 180-angle;
            glRotatef( angle, 0.0f, 0.0f, 1.0f );
            glTranslatef( m2*10.0f, 0.0f, 0.0f );
            glScalef( sqrt(fabs(b.p2.getY()+0.1)), 1.0f, 1.0f );
            double angle2 = -asin( my/m )*180.f/3.14259265f;
            if ( mx>0.0 ) angle2 = 180-angle2;
            glRotatef( -angle+angle2+90.0f, 0.0f, 0.0f, 1.0f );
            glBindTexture( GL_TEXTURE_2D, textures[7] ); // number
            glBegin(GL_QUADS);
                glTexCoord2f( 0.0f, (16-num)/15.0f ); glVertex2f( -5.0f, -5.0f );
                glTexCoord2f( 0.0f, (15-num)/15.0f ); glVertex2f( -5.0f, 5.0f );
                glTexCoord2f( 1.0f, (15-num)/15.0f ); glVertex2f( 5.0f, 5.0f );
                glTexCoord2f( 1.0f, (16-num)/15.0f ); glVertex2f( 5.0f, -5.0f );
            glEnd();
            glPopMatrix();
        }

        glClear( GL_STENCIL_BUFFER_BIT );
        glDisable( GL_STENCIL_TEST );
    }

    glColor3f( 1.0f, 1.0f, 1.0f );
    glBindTexture( GL_TEXTURE_2D, textures[6] ); // reflection
    glBegin(GL_QUADS);
        glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -10.0f, -10.0f );
        glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -10.0f, 10.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 8.0f, 10.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 8.0f, -10.0f );
    glEnd();

//    drawCircle( x, y, 9.0f );

    glPopMatrix();
}

void CTestScreen::draw(CGraphics *gl)
{
    glLoadIdentity();
    glColor3f(1.0f, 1.0f, 1.0f );

    glBindTexture(GL_TEXTURE_2D,textures[0]);   // fonas ir stalo šonai
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f,1.0f); glVertex2f( 0, 0 );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 0, 500 );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 700, 500 );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 700, 0 );
    glEnd();

    for ( int i = 0; i < balls.size(); i++ ) {  // tik kamuoliukai po stalu
        if ( balls[i].status < 6 )
            continue;
        drawBall( gl, balls[i] );
    }

    glBindTexture(GL_TEXTURE_2D,textures[1]);   // stalas
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f,1.0f); glVertex2f( 47, (68) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 47, (382) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 651, (382) );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 651, (68) );
    glEnd();

    for ( int i = 0; i < balls.size(); i++ ) {
        if ( balls[i].status > -1 ) continue;
        glColor4f( 1.0f, 1.0f, 1.0f, 0.8f );
        glBindTexture(GL_TEXTURE_2D,textures[5]);   // Kamuoliuko šėšėlis
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f,1.0f); glVertex2f( -balls[i].radius-6+((balls[i].pos.getX()-350)/100.0f)+balls[i].pos.getX(), (-balls[i].radius-8+((balls[i].pos.getY()-225)/50.0f)+balls[i].pos.getY()) );
            glTexCoord2f(0.0f,0.0f); glVertex2f( -balls[i].radius-6+((balls[i].pos.getX()-350)/100.0f)+balls[i].pos.getX(), (balls[i].radius+6+((balls[i].pos.getY()-225)/50.0f)+balls[i].pos.getY()) );
            glTexCoord2f(1.0f,0.0f); glVertex2f( balls[i].radius+6+((balls[i].pos.getX()-350)/100.0f)+balls[i].pos.getX(), (balls[i].radius+6+((balls[i].pos.getY()-225)/50.0f)+balls[i].pos.getY()) );
            glTexCoord2f(1.0f,1.0f); glVertex2f( balls[i].radius+6+((balls[i].pos.getX()-350)/100.0f)+balls[i].pos.getX(), (-balls[i].radius-8+((balls[i].pos.getY()-225)/50.0f)+balls[i].pos.getY()) );
        glEnd();
    }
    
    glColor3f(1.0f, 1.0f, 1.0f );
    glBindTexture(GL_TEXTURE_2D,textures[2]);   // Stalo vidinės sienos
    glBegin(GL_QUADS);
        glTexCoord2f(0.0f,1.0f); glVertex2f( 62, (68) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 62, (87) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 340, (87) );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 340, (68) );

        glTexCoord2f(1.0f,1.0f); glVertex2f( 357, (68) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 357, (87) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 635, (87) );
        glTexCoord2f(0.0f,1.0f); glVertex2f( 635, (68) );

        glTexCoord2f(0.0f,0.0f); glVertex2f( 62, (363) );
        glTexCoord2f(0.0f,1.0f); glVertex2f( 62, (382) );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 340, (382) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 340, (363) );

        glTexCoord2f(1.0f,0.0f); glVertex2f( 357, (363) );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 357, (382) );
        glTexCoord2f(0.0f,1.0f); glVertex2f( 635, (382) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 635, (363) );
    glEnd();

    glBindTexture(GL_TEXTURE_2D,textures[3]); // stalo vidines sienelės
    glBegin(GL_QUADS);    
        glTexCoord2f(0.0f,1.0f); glVertex2f( 47, (84) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 47, (366) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 66, (366) );
        glTexCoord2f(1.0f,1.0f); glVertex2f( 66, (84) );

        glTexCoord2f(1.0f,1.0f); glVertex2f( 632, (84) );
        glTexCoord2f(1.0f,0.0f); glVertex2f( 632, (366) );
        glTexCoord2f(0.0f,0.0f); glVertex2f( 651, (366) );
        glTexCoord2f(0.0f,1.0f); glVertex2f( 651, (84) );
    glEnd();

    for ( int i = 0; i < balls.size(); i++ ) {  //neimušti kamuoliukai
        if ( balls[i].status > 5 )
            continue;
        drawBall( gl, balls[i] );
//        drawCircle( gl, balls[i].pos, balls[i].radius, 255, 255, 255, 155 );
//        drawArrow( gl, balls[i].pos, balls[i].pos+balls[i].speed, 155, 255, 155, 155 );
    }

    if ( (gameState == 0 || gameState == 1) && balls.size() > 0 ) {
        glColor4f(1.0f, 1.0f, 1.0f, 0.5f );

        glTranslatef( balls[0].pos.getX(), balls[0].pos.getY(), 0.0f );
        double angle;
        if ( hitDirection.getY() < 0 )
            angle = atan(hitDirection.getX()/hitDirection.getY()+0.000001)*180/3.14159+180;
        else
            angle = atan(hitDirection.getX()/hitDirection.getY()+0.000001)*180/3.14159;
        glRotatef( -angle, 0.0f, 0.0f, 1.0f );
        glTranslatef( -7.5f, -338.0f-balls[0].radius/2-hitForce, 0.0f );

        glColor3f(1.0f, 1.0f, 1.0f );
        glBindTexture(GL_TEXTURE_2D,textures[9]);
        glBegin(GL_QUADS);
            glTexCoord2f(0.0f,1.0f); glVertex2f( 0, 342 );
            glTexCoord2f(0.0f,0.0f); glVertex2f( 0, 0 );
            glTexCoord2f(1.0f,0.0f); glVertex2f( 13, 0 );
            glTexCoord2f(1.0f,1.0f); glVertex2f( 13, 342 );
        glEnd();
        glLoadIdentity();
    }

//    for ( int i = 0; i < splines.size(); i++ )
//    {
//        TSpline sp = splines[i];
//        if ( spline == i )
//            drawLine( gl, sp.p1, sp.p2, 255, 155, 155, 155 );
//        else
//            drawLine( gl, sp.p1, sp.p2, 255, 255, 255, 155 );
//        drawArrow( gl, sp.p1, sp.p1+(sp.p2-sp.p1).rightNormal().direction()*15 , 255, 255, 255, 155 );
//    }
//    for ( int i = 0; i < holes.size(); i++ ) {
//        drawCircle( gl, holes[i].pos, holes[i].radius, 255, 155, 155, 155 );
//    }

    if ( gameState == 0 || gameState == 1 ) {
        drawLine( gl, balls[0].pos, collidePos, 255, 255, 255, 200 );
        drawLine( gl, collidePos, collidePos+bounceDir*30.0, 255, 255, 255, 200 );
        drawCircle( gl, collidePos, balls[0].radius, 255, 255, 255, 200 );
        if ( bounceBall > 0 && bounceBall < balls.size() )
            drawLine( gl, balls[bounceBall].pos, balls[bounceBall].pos+bounceDir2, 255, 255, 255, 200 );
    }

    glColor4f(1.0f, 1.0f, 1.0f, 0.9f );
    if ( statusTime > 0.0 || statusTime == -1.0 ) {
        gl->renderTexts( 30, 430, status, font );
    }

    if ( gameType == 0 ) {
        if ( gameState != 5 ) {
            if ( stripedPlayer == 1 ) {
                gl->renderTexts( 30, 450, QString::fromStdWString(L"Pirmasis žaidėjas - dryžuoti kamuoliukai (9-15). Liko: ") + QString::number(ballsLeft[1]), font );
                gl->renderTexts( 30, 470, QString::fromStdWString(L"Antrasis žaidėjas - vienspalviai kamuoliukai (1-7). Liko: ") + QString::number(ballsLeft[2]), font );
            } else if ( stripedPlayer == 2 ) {
                gl->renderTexts( 30, 450, QString::fromStdWString(L"Pirmasis žaidėjas - vienspalviai kamuoliukai (1-7). Liko: ") + QString::number(ballsLeft[1]), font );
                gl->renderTexts( 30, 470, QString::fromStdWString(L"Antrasis žaidėjas - dryžuoti kamuoliukai (9-15). Liko: ") + QString::number(ballsLeft[2]), font );
            }
        }
        if ( gameState == 5 ) {
            gl->renderTexts( 30, 450, QString::fromStdWString(L"Enter - Naujas žaidmas"), font );
        }
    } else if ( gameType == 1 ) {
        if ( gameState == 5 ) {
            gl->renderTexts( 30, 450, QString::fromStdWString(L"Enter - Naujas žaidmas"), font );
        } else {
            if ( lowestBall > 0 && lowestBall < 10 )
                gl->renderTexts( 30, 450, QString::fromStdWString(L"Sekantis kamuoliukas: ") + QString::number(lowestBall), font );
        }
    } else if ( gameType == 2 ) {
        gl->renderTexts( 30, 450, QString::fromStdWString(L"Taškai: ") + QString::number(points), font );
        gl->renderTexts( 30, 470, QString::fromStdWString(L"Laikas: ") + QString::number(((int)timeLeft)/60) + QString(((((int)timeLeft)%60<10)?":0":":")) + QString::number(((int)timeLeft)%60), font );
    }

}

void CTestScreen::setGameSettings( int gameType, int players ) {

    this->gameType = gameType;
    this->players = players;

    if ( gameType == 0 ) { // 8 pool

        sm->getSound()->play("audio/opr000L0-13.mp3");

        // kamuoliukų sąrašas
        balls.clear(); // 255.0, 300.0 -52 -75
        double pos[] = { 203.0, 225.0, 553.0, 245.0, 508.0, 235.0, 538.0, 195.0,
                         508.0, 215.0, 553.0, 265.0, 523.0, 245.0, 553.0, 205.0,
                         523.0, 225.0, 493.0, 225.0, 523.0, 205.0, 538.0, 215.0,
                         553.0, 225.0, 553.0, 185.0, 538.0, 235.0, 538.0, 255.0, };
        TBall bl = { CVect2d(0.0, 0.0), CVect2d(0.0, 0.0), 9, 255, 255, 255, false, 0, -1,
                     CVect3d( 0.0, 0.0, 1.0 ), CVect3d( 0.0, 1.0, 0.0 ) };
        for ( int i = 0; i < 16; i++ ) {
            bl.pos.set( pos[2*i], pos[2*i+1] );
            bl.number = i%16;
            bl.r = col[i%16][0]/255.0f;
            bl.g = col[i%16][1]/255.0f;
            bl.b = col[i%16][2]/255.0f;
            balls.append(bl);
        }

        playersTurn = 1;
        stripedPlayer = 0;
        gameState = 0;
        firstHitBall = -1;
        ballsLeft[1] = 8;
        ballsLeft[2] = 8;

        status = QString::fromStdWString(L"Pirmasis žaidėjas pradeda");
        statusTime = -1.0;

    } else if ( gameType == 1 ) { // 9 ball

        sm->getSound()->play("audio/opr000L0-13.mp3");

        // kamuoliukų sąrašas
        balls.clear();
        double pos[] = { 203.0, 225.0, 493.0, 225.0, 553.0, 225.0, 508.0, 235.0,
                         538.0, 235.0, 508.0, 215.0, 523.0, 245.0, 538.0, 215.0,
                         523.0, 205.0, 523.0, 225.0, };
        TBall bl = { CVect2d(0.0, 0.0), CVect2d(0.0, 0.0), 9, 255, 255, 255, false, 0, -1,
                     CVect3d( 0.0, 0.0, 1.0 ), CVect3d( 0.0, 1.0, 0.0 ) };
        for ( int i = 0; i < 10; i++ ) {
            bl.pos.set( pos[2*i], pos[2*i+1] );
            bl.number = i%16;
            bl.r = col[i%16][0]/255.0f;
            bl.g = col[i%16][1]/255.0f;
            bl.b = col[i%16][2]/255.0f;
            balls.append(bl);
        }

        playersTurn = 1;
        gameState = 0;
        firstHitBall = -1;
        lowestBall = 1;

        status = QString::fromStdWString(L"Pirmasis žaidėjas pradeda");
        statusTime = -1.0;
    } else if ( gameType == 2 ) { // " Quick pool

        sm->getSound()->play("audio/opr000L0-13.mp3");

        // kamuoliukų sąrašas
        balls.clear(); // 255.0, 300.0 -52 -75
        double pos[] = { 203.0, 225.0, 553.0, 245.0, 508.0, 235.0, 538.0, 195.0,
                         508.0, 215.0, 553.0, 265.0, 523.0, 245.0, 553.0, 205.0,
                         523.0, 225.0, 493.0, 225.0, 523.0, 205.0, 538.0, 215.0,
                         553.0, 225.0, 553.0, 185.0, 538.0, 235.0, 538.0, 255.0, };
        TBall bl = { CVect2d(0.0, 0.0), CVect2d(0.0, 0.0), 9, 255, 255, 255, false, 0, -1,
                     CVect3d( 0.0, 0.0, 1.0 ), CVect3d( 0.0, 1.0, 0.0 ) };
        for ( int i = 0; i < 16; i++ ) {
            bl.pos.set( pos[2*i], pos[2*i+1] );
            bl.number = i%16;
            bl.r = col[i%16][0]/255.0f;
            bl.g = col[i%16][1]/255.0f;
            bl.b = col[i%16][2]/255.0f;
            balls.append(bl);
        }

        gameState = 0;
        firstHitBall = -1;
        ballsLeft[0] = 15;
        timeLeft = 180.0;
        points = 0;

        status = QString::fromStdWString(L"Quick pool");
        statusTime = -1.0;
    }

    winner = 0;
    hitForce = 0;
    touchedSpline = false;
    hitDirection.set( 0.0, 0.0 );
    hitPoint.set( 0.0, 0.0 );
    collidePos.set( 0.0, 0.0 );
    bounceDir.set( 0.0, 0.0 );
    bounceDir2.set( 0.0, 0.0 );
    bounceBall = -1;

}
